/**
 * @file snakecreateroomdialog.cpp
 * @brief Snake游戏创建房间对话框类实现文件
 *
 * 实现Snake游戏房间创建对话框的所有功能，包括：
 * - UI界面的创建和布局
 * - 用户输入的验证和处理
 * - 房间配置的生成和管理
 * - 用户体验优化
 */

#include "../include/snakecreateroomdialog.h"
#include "../include/config.h"
#include <QDebug>               // 调试输出
#include <QMessageBox>          // 消息框
#include <QDateTime>            // 时间处理

/**
 * @brief SnakeCreateRoomDialog构造函数
 * @param parent 父窗口部件指针
 *
 * 初始化Snake游戏创建房间对话框：
 * 1. 设置对话框属性
 * 2. 创建UI界面
 * 3. 设置默认值
 * 4. 建立信号槽连接
 */
SnakeCreateRoomDialog::SnakeCreateRoomDialog(QWidget *parent)
    : QDialog(parent)
    , m_mainLayout(nullptr)
{
    // === 设置对话框属性 ===
    setWindowTitle("Create Snake Game Room");
    setModal(true);
    setFixedSize(400, 500);
    
    // === 设置默认配置 ===
    m_defaultConfig.roomName = QString("Room_%1").arg(QDateTime::currentSecsSinceEpoch());
    m_defaultConfig.maxPlayers = 4;
    m_defaultConfig.gameMode = 1;
    m_defaultConfig.mapWidth = 40;
    m_defaultConfig.mapHeight = 30;
    m_defaultConfig.gameSpeedMs = 100;
    m_defaultConfig.enableWalls = true;
    m_defaultConfig.enableSpecialFoods = false;
    m_defaultConfig.maxFoodCount = 10;
    
    // === 设置UI界面 ===
    setupUI();
    
    // === 建立信号槽连接 ===
    setupConnections();
    
    // === 重置为默认值 ===
    resetToDefaults();
    
    qDebug() << "SnakeCreateRoomDialog initialized";
}

/**
 * @brief SnakeCreateRoomDialog析构函数
 */
SnakeCreateRoomDialog::~SnakeCreateRoomDialog()
{
    qDebug() << "SnakeCreateRoomDialog destroyed";
}

/**
 * @brief 获取房间配置
 * @return 房间配置结构
 */
SnakeGameManager::GameConfig SnakeCreateRoomDialog::getRoomConfig() const
{
    SnakeGameManager::GameConfig config;
    
    config.roomName = m_roomNameEdit->text().trimmed();
    config.maxPlayers = m_maxPlayersSpinBox->value();
    config.gameMode = m_gameModeComboBox->currentIndex() + 1;
    config.mapWidth = m_mapWidthSpinBox->value();
    config.mapHeight = m_mapHeightSpinBox->value();
    config.gameSpeedMs = m_gameSpeedSpinBox->value();
    config.enableWalls = m_enableWallsCheckBox->isChecked();
    config.enableSpecialFoods = m_enableSpecialFoodsCheckBox->isChecked();
    config.maxFoodCount = m_maxFoodSpinBox->value();
    
    return config;
}

/**
 * @brief 设置默认房间配置
 * @param config 默认配置
 */
void SnakeCreateRoomDialog::setDefaultConfig(const SnakeGameManager::GameConfig &config)
{
    m_defaultConfig = config;
    resetToDefaults();
}

/**
 * @brief 重置为默认值
 */
void SnakeCreateRoomDialog::resetToDefaults()
{
    m_roomNameEdit->setText(m_defaultConfig.roomName);
    m_maxPlayersSpinBox->setValue(m_defaultConfig.maxPlayers);
    m_gameModeComboBox->setCurrentIndex(m_defaultConfig.gameMode - 1);
    m_mapWidthSpinBox->setValue(m_defaultConfig.mapWidth);
    m_mapHeightSpinBox->setValue(m_defaultConfig.mapHeight);
    m_gameSpeedSpinBox->setValue(m_defaultConfig.gameSpeedMs);
    m_enableWallsCheckBox->setChecked(m_defaultConfig.enableWalls);
    m_enableSpecialFoodsCheckBox->setChecked(m_defaultConfig.enableSpecialFoods);
    m_maxFoodSpinBox->setValue(m_defaultConfig.maxFoodCount);
    
    updateGameSpeedLabel();
}

/**
 * @brief 接受按钮点击处理
 */
void SnakeCreateRoomDialog::onAcceptClicked()
{
    if (validateInput()) {
        accept();
    }
}

/**
 * @brief 重置按钮点击处理
 */
void SnakeCreateRoomDialog::onResetClicked()
{
    resetToDefaults();
}

/**
 * @brief 游戏模式改变处理
 * @param index 模式索引
 */
void SnakeCreateRoomDialog::onGameModeChanged(int index)
{
    Q_UNUSED(index)
    
    // === 根据游戏模式调整其他设置 ===
    // 可以在这里添加模式特定的逻辑
}

/**
 * @brief 地图大小改变处理
 */
void SnakeCreateRoomDialog::onMapSizeChanged()
{
    // === 更新地图大小预设选择 ===
    int width = m_mapWidthSpinBox->value();
    int height = m_mapHeightSpinBox->value();
    
    QString sizeText = QString("%1x%2").arg(width).arg(height);
    
    // === 检查是否匹配预设 ===
    int presetIndex = m_mapSizePresetComboBox->findText(sizeText);
    if (presetIndex >= 0) {
        m_mapSizePresetComboBox->setCurrentIndex(presetIndex);
    } else {
        m_mapSizePresetComboBox->setCurrentIndex(0); // Custom
    }
}

/**
 * @brief 游戏速度改变处理
 * @param value 速度值
 */
void SnakeCreateRoomDialog::onGameSpeedChanged(int value)
{
    Q_UNUSED(value)
    updateGameSpeedLabel();
}

/**
 * @brief 设置UI界面
 */
void SnakeCreateRoomDialog::setupUI()
{
    m_mainLayout = new QVBoxLayout(this);
    m_mainLayout->setContentsMargins(Config::getStandardMargin(), Config::getStandardMargin(),
                                    Config::getStandardMargin(), Config::getStandardMargin());
    m_mainLayout->setSpacing(Config::getStandardSpacing());
    
    setupBasicSettings();
    setupMapSettings();
    setupGameSettings();
    setupAdvancedSettings();
    setupButtons();
}

/**
 * @brief 设置基本设置组
 */
void SnakeCreateRoomDialog::setupBasicSettings()
{
    m_basicGroupBox = new QGroupBox("Basic Settings");
    m_basicFormLayout = new QFormLayout(m_basicGroupBox);
    
    // === 房间名称 ===
    m_roomNameEdit = new QLineEdit();
    m_roomNameEdit->setPlaceholderText("Enter room name...");
    m_roomNameEdit->setMaxLength(50);
    m_basicFormLayout->addRow("Room Name:", m_roomNameEdit);
    
    // === 最大玩家数 ===
    m_maxPlayersSpinBox = new QSpinBox();
    m_maxPlayersSpinBox->setRange(2, 8);
    m_maxPlayersSpinBox->setSuffix(" players");
    m_basicFormLayout->addRow("Max Players:", m_maxPlayersSpinBox);
    
    // === 游戏模式 ===
    m_gameModeComboBox = new QComboBox();
    m_gameModeComboBox->addItems({"Classic", "Speed", "Survival", "Team"});
    m_basicFormLayout->addRow("Game Mode:", m_gameModeComboBox);
    
    m_mainLayout->addWidget(m_basicGroupBox);
}

/**
 * @brief 设置地图设置组
 */
void SnakeCreateRoomDialog::setupMapSettings()
{
    m_mapGroupBox = new QGroupBox("Map Settings");
    m_mapFormLayout = new QFormLayout(m_mapGroupBox);
    
    // === 地图大小预设 ===
    m_mapSizePresetComboBox = new QComboBox();
    m_mapSizePresetComboBox->addItems({"Custom", "Small (30x20)", "Medium (40x30)", 
                                      "Large (50x40)", "Huge (60x45)"});
    m_mapFormLayout->addRow("Size Preset:", m_mapSizePresetComboBox);
    
    // === 地图宽度 ===
    m_mapWidthSpinBox = new QSpinBox();
    m_mapWidthSpinBox->setRange(20, 100);
    m_mapWidthSpinBox->setSuffix(" cells");
    m_mapFormLayout->addRow("Width:", m_mapWidthSpinBox);
    
    // === 地图高度 ===
    m_mapHeightSpinBox = new QSpinBox();
    m_mapHeightSpinBox->setRange(15, 75);
    m_mapHeightSpinBox->setSuffix(" cells");
    m_mapFormLayout->addRow("Height:", m_mapHeightSpinBox);
    
    m_mainLayout->addWidget(m_mapGroupBox);
}

/**
 * @brief 设置游戏设置组
 */
void SnakeCreateRoomDialog::setupGameSettings()
{
    m_gameGroupBox = new QGroupBox("Game Settings");
    m_gameFormLayout = new QFormLayout(m_gameGroupBox);
    
    // === 游戏速度 ===
    m_gameSpeedSpinBox = new QSpinBox();
    m_gameSpeedSpinBox->setRange(50, 500);
    m_gameSpeedSpinBox->setSingleStep(10);
    m_gameSpeedSpinBox->setSuffix(" ms");
    m_gameSpeedLabel = new QLabel();
    QHBoxLayout *speedLayout = new QHBoxLayout();
    speedLayout->addWidget(m_gameSpeedSpinBox);
    speedLayout->addWidget(m_gameSpeedLabel);
    speedLayout->addStretch();
    m_gameFormLayout->addRow("Game Speed:", speedLayout);
    
    // === 最大食物数 ===
    m_maxFoodSpinBox = new QSpinBox();
    m_maxFoodSpinBox->setRange(5, 50);
    m_maxFoodSpinBox->setSuffix(" foods");
    m_gameFormLayout->addRow("Max Food:", m_maxFoodSpinBox);
    
    m_mainLayout->addWidget(m_gameGroupBox);
}

/**
 * @brief 设置高级设置组
 */
void SnakeCreateRoomDialog::setupAdvancedSettings()
{
    m_advancedGroupBox = new QGroupBox("Advanced Settings");
    m_advancedLayout = new QVBoxLayout(m_advancedGroupBox);
    
    // === 启用墙壁 ===
    m_enableWallsCheckBox = new QCheckBox("Enable Walls");
    m_enableWallsCheckBox->setToolTip("Snakes die when hitting walls");
    m_advancedLayout->addWidget(m_enableWallsCheckBox);
    
    // === 启用特殊食物 ===
    m_enableSpecialFoodsCheckBox = new QCheckBox("Enable Special Foods");
    m_enableSpecialFoodsCheckBox->setToolTip("Add special foods with bonus effects");
    m_advancedLayout->addWidget(m_enableSpecialFoodsCheckBox);
    
    m_mainLayout->addWidget(m_advancedGroupBox);
}

/**
 * @brief 设置按钮
 */
void SnakeCreateRoomDialog::setupButtons()
{
    m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
    m_resetButton = new QPushButton("Reset to Defaults");
    
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addWidget(m_resetButton);
    buttonLayout->addStretch();
    buttonLayout->addWidget(m_buttonBox);
    
    m_mainLayout->addLayout(buttonLayout);
}

/**
 * @brief 建立信号槽连接
 */
void SnakeCreateRoomDialog::setupConnections()
{
    // === 按钮连接 ===
    connect(m_buttonBox, &QDialogButtonBox::accepted,
            this, &SnakeCreateRoomDialog::onAcceptClicked);
    connect(m_buttonBox, &QDialogButtonBox::rejected,
            this, &QDialog::reject);
    connect(m_resetButton, &QPushButton::clicked,
            this, &SnakeCreateRoomDialog::onResetClicked);
    
    // === 控件连接 ===
    connect(m_gameModeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &SnakeCreateRoomDialog::onGameModeChanged);
    connect(m_mapWidthSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
            this, &SnakeCreateRoomDialog::onMapSizeChanged);
    connect(m_mapHeightSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
            this, &SnakeCreateRoomDialog::onMapSizeChanged);
    connect(m_gameSpeedSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
            this, &SnakeCreateRoomDialog::onGameSpeedChanged);
    
    // === 地图大小预设连接 ===
    connect(m_mapSizePresetComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
            this, &SnakeCreateRoomDialog::updateMapSizeFromPreset);
}

/**
 * @brief 更新游戏速度标签
 */
void SnakeCreateRoomDialog::updateGameSpeedLabel()
{
    int speed = m_gameSpeedSpinBox->value();
    QString speedText;

    if (speed <= 80) {
        speedText = "(Very Fast)";
    } else if (speed <= 120) {
        speedText = "(Fast)";
    } else if (speed <= 180) {
        speedText = "(Normal)";
    } else if (speed <= 250) {
        speedText = "(Slow)";
    } else {
        speedText = "(Very Slow)";
    }

    m_gameSpeedLabel->setText(speedText);
}

/**
 * @brief 从预设更新地图大小
 */
void SnakeCreateRoomDialog::updateMapSizeFromPreset()
{
    int presetIndex = m_mapSizePresetComboBox->currentIndex();

    switch (presetIndex) {
    case 1: // Small (30x20)
        m_mapWidthSpinBox->setValue(30);
        m_mapHeightSpinBox->setValue(20);
        break;
    case 2: // Medium (40x30)
        m_mapWidthSpinBox->setValue(40);
        m_mapHeightSpinBox->setValue(30);
        break;
    case 3: // Large (50x40)
        m_mapWidthSpinBox->setValue(50);
        m_mapHeightSpinBox->setValue(40);
        break;
    case 4: // Huge (60x45)
        m_mapWidthSpinBox->setValue(60);
        m_mapHeightSpinBox->setValue(45);
        break;
    default: // Custom - 不改变当前值
        break;
    }
}

/**
 * @brief 验证输入
 * @return true表示输入有效
 */
bool SnakeCreateRoomDialog::validateInput()
{
    // === 验证房间名称 ===
    QString roomName = m_roomNameEdit->text().trimmed();
    if (roomName.isEmpty()) {
        showValidationError("Room name cannot be empty.");
        m_roomNameEdit->setFocus();
        return false;
    }

    if (roomName.length() < 3) {
        showValidationError("Room name must be at least 3 characters long.");
        m_roomNameEdit->setFocus();
        return false;
    }

    // === 验证地图大小 ===
    int mapWidth = m_mapWidthSpinBox->value();
    int mapHeight = m_mapHeightSpinBox->value();
    int maxPlayers = m_maxPlayersSpinBox->value();

    // 检查地图是否足够大以容纳所有玩家
    int minCells = maxPlayers * 10; // 每个玩家至少需要10个单元格
    if (mapWidth * mapHeight < minCells) {
        showValidationError(QString("Map is too small for %1 players. "
                                   "Minimum size needed: %2 cells.")
                           .arg(maxPlayers).arg(minCells));
        return false;
    }

    // === 验证游戏速度 ===
    int gameSpeed = m_gameSpeedSpinBox->value();
    if (gameSpeed < 50 || gameSpeed > 500) {
        showValidationError("Game speed must be between 50ms and 500ms.");
        m_gameSpeedSpinBox->setFocus();
        return false;
    }

    return true;
}

/**
 * @brief 显示验证错误
 * @param message 错误消息
 */
void SnakeCreateRoomDialog::showValidationError(const QString &message)
{
    QMessageBox::warning(this, "Invalid Input", message);
}
